package com.quyunshuo.module.home.activity.stat.chart;

import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Shader;
import android.graphics.drawable.Drawable;

import com.github.mikephil.charting.animation.ChartAnimator;
import com.github.mikephil.charting.buffer.BarBuffer;
import com.github.mikephil.charting.data.BarEntry;
import com.github.mikephil.charting.formatter.ValueFormatter;
import com.github.mikephil.charting.interfaces.dataprovider.BarDataProvider;
import com.github.mikephil.charting.interfaces.datasets.IBarDataSet;
import com.github.mikephil.charting.renderer.BarChartRenderer;
import com.github.mikephil.charting.utils.MPPointF;
import com.github.mikephil.charting.utils.Transformer;
import com.github.mikephil.charting.utils.Utils;
import com.github.mikephil.charting.utils.ViewPortHandler;

import java.util.List;

// 柱状图的自定义渲染器，继承自MPAndroidChart的柱状图渲染器
public class BarChartRender extends BarChartRenderer {

    public BarChartRender(BarDataProvider chart, ChartAnimator animator, ViewPortHandler viewPortHandler) {
        super(chart, animator, viewPortHandler);
    }

    // 暂时不用看，我们没用到  数值标签
    @Override
    public void drawValues(Canvas c) {
        // 检查是否允许绘制数值
        if (this.isDrawingValuesAllowed(this.mChart)) {
            List<IBarDataSet> dataSets = this.mChart.getBarData().getDataSets();
            float valueOffsetPlus = Utils.convertDpToPixel(4.5F); // 数值标签的垂直偏移量
            float posOffset = 0.0F; // 正值的偏移量
            float negOffset = 0.0F; // 负值的偏移量
            boolean drawValueAboveBar = this.mChart.isDrawValueAboveBarEnabled(); // 是否在柱上方绘制数值

            // 遍历所有数据集
            for (int i = 0; i < this.mChart.getBarData().getDataSetCount(); ++i) {
                IBarDataSet dataSet = (IBarDataSet) dataSets.get(i);
                if (this.shouldDrawValues(dataSet)) { // 检查该数据集是否需要绘制数值
                    this.applyValueTextStyle(dataSet); // 应用数值文本样式
                    boolean isInverted = this.mChart.isInverted(dataSet.getAxisDependency()); // 检查坐标系是否反转
                    float valueTextHeight = (float) Utils.calcTextHeight(this.mValuePaint, "8"); // 计算文本高度
                    // 根据绘制位置计算偏移量
                    posOffset = drawValueAboveBar ? -valueOffsetPlus : valueTextHeight + valueOffsetPlus;
                    negOffset = drawValueAboveBar ? valueTextHeight + valueOffsetPlus : -valueOffsetPlus;
                    if (isInverted) { // 反转坐标系时调整偏移量
                        posOffset = -posOffset - valueTextHeight;
                        negOffset = -negOffset - valueTextHeight;
                    }

                    BarBuffer buffer = this.mBarBuffers[i]; // 获取当前数据集的缓冲区
                    float phaseY = this.mAnimator.getPhaseY(); // 获取Y轴动画相位
                    ValueFormatter formatter = dataSet.getValueFormatter(); // 数值格式化器
                    MPPointF iconsOffset = MPPointF.getInstance(dataSet.getIconsOffset()); // 图标偏移量
                    iconsOffset.x = Utils.convertDpToPixel(iconsOffset.x);
                    iconsOffset.y = Utils.convertDpToPixel(iconsOffset.y);
                    float x;
                    // 处理非堆叠柱状图
                    if (!dataSet.isStacked()) {
                        // 遍历缓冲区中的每个柱
                        for (int j = 0; (float) j < (float) buffer.buffer.length * this.mAnimator.getPhaseX(); j += 4) {
                            x = (buffer.buffer[j] + buffer.buffer[j + 2]) / 2.0F; // 计算柱的中心X坐标
                            if (!this.mViewPortHandler.isInBoundsRight(x)) { // 检查是否超出右边界
                                break;
                            }

                            // 检查当前柱是否在可见区域内
                            if (this.mViewPortHandler.isInBoundsY(buffer.buffer[j + 1]) && this.mViewPortHandler.isInBoundsLeft(x)) {
                                BarEntry entry = (BarEntry) dataSet.getEntryForIndex(j / 4); // 获取数据点
                                float val = entry.getY();
                                // 绘制数值标签
//                                if (dataSet.isDrawValuesEnabled()) {
//                                    this.drawValue(c, formatter.getBarLabel(entry), x,
//                                            val >= 0.0F ? buffer.buffer[j + 1] + posOffset : buffer.buffer[j + 3] + negOffset,
//                                            dataSet.getValueTextColor(j / 4));
//                                }

                                // 绘制图标（如果有）
                                if (entry.getIcon() != null && dataSet.isDrawIconsEnabled()) {
                                    Drawable icon = entry.getIcon();
                                    float py = val >= 0.0F ? buffer.buffer[j + 1] + posOffset : buffer.buffer[j + 3] + negOffset;
                                    Utils.drawImage(c, icon,
                                            (int)(x + iconsOffset.x),
                                            (int)(py + iconsOffset.y),
                                            icon.getIntrinsicWidth(),
                                            icon.getIntrinsicHeight());
                                }
                            }
                        }
                    } else { // 处理堆叠柱状图
                        Transformer trans = this.mChart.getTransformer(dataSet.getAxisDependency());
                        int bufferIndex = 0;
                        int index = 0;

                        // 遍历所有数据点
                        while (index < dataSet.getEntryCount() * this.mAnimator.getPhaseX()) {
                            BarEntry entry = (BarEntry) dataSet.getEntryForIndex(index);
                            float[] vals = entry.getYVals(); // 获取堆叠值数组
                            x = (buffer.buffer[bufferIndex] + buffer.buffer[bufferIndex + 2]) / 2.0F; // 柱的中心X坐标
                            int color = dataSet.getValueTextColor(index); // 获取文本颜色

                            if (vals == null) { // 非堆叠柱处理
                                if (!this.mViewPortHandler.isInBoundsRight(x)) break;

                                if (this.mViewPortHandler.isInBoundsY(buffer.buffer[bufferIndex + 1]) &&
                                        this.mViewPortHandler.isInBoundsLeft(x)) {

                                    // 绘制数值
//                                    if (dataSet.isDrawValuesEnabled()) {
//                                        this.drawValue(c, formatter.getBarLabel(entry), x,
//                                                buffer.buffer[bufferIndex + 1] + negOffset, color);
//                                    }

                                    // 绘制图标
                                    if (entry.getIcon() != null && dataSet.isDrawIconsEnabled()) {
                                        Drawable icon = entry.getIcon();
                                        float px = x + iconsOffset.x;
                                        float py = buffer.buffer[bufferIndex + 1] +
                                                (entry.getY() >= 0.0F ? posOffset : negOffset) +
                                                iconsOffset.y;

                                        Utils.drawImage(c, icon, (int)px, (int)py,
                                                icon.getIntrinsicWidth(), icon.getIntrinsicHeight());
                                    }
                                }
                            } else { // 堆叠柱处理
                                // 创建转换后的坐标数组
                                float[] transformed = new float[vals.length * 2];
                                float posY = 0.0F;
                                float negY = -entry.getNegativeSum();

                                // 计算每个堆叠部分的Y坐标
                                for (int k = 0, idx = 0; k < transformed.length; k += 2, idx++) {
                                    float value = vals[idx];
                                    float y;
                                    if (value >= 0.0F) {
                                        posY += value;
                                        y = posY;
                                    } else {
                                        y = negY;
                                        negY -= value;
                                    }
                                    transformed[k + 1] = y * phaseY; // 应用动画相位
                                }

                                trans.pointValuesToPixel(transformed); // 转换为像素坐标

                                // 绘制每个堆叠部分的值
                                for (int k = 0; k < transformed.length; k += 2) {
                                    float val = vals[k / 2];
                                    float y = transformed[k + 1] + negOffset; // 应用偏移

                                    if (!this.mViewPortHandler.isInBoundsRight(x)) break;

                                    if (this.mViewPortHandler.isInBoundsY(y) &&
                                            this.mViewPortHandler.isInBoundsLeft(x)) {

                                        // 只绘制正值（可能只需要显示正值）
                                        if (dataSet.isDrawValuesEnabled() && val > 0) {
                                            this.drawValue(c, formatter.getBarStackedLabel(val, entry),
                                                    x, y, color);
                                        }
                                    }
                                }
                            }

                            // 更新缓冲区索引（根据是否堆叠）
                            bufferIndex = vals == null ? bufferIndex + 4 : bufferIndex + 4 * vals.length;
                            ++index;
                        }
                    }
                    MPPointF.recycleInstance(iconsOffset); // 回收图标偏移对象
                }
            }
        }
    }

    @Override
    protected void drawDataSet(Canvas c, IBarDataSet dataSet, int index) {
        // 获取坐标转换器
        Transformer trans = this.mChart.getTransformer(dataSet.getAxisDependency());

        // 设置柱边框样式
        this.mBarBorderPaint.setColor(dataSet.getBarBorderColor());
        this.mBarBorderPaint.setStrokeWidth(Utils.convertDpToPixel(dataSet.getBarBorderWidth()));

        // 获取动画相位
        float phaseX = this.mAnimator.getPhaseX();
        float phaseY = this.mAnimator.getPhaseY();

        // 获取并配置缓冲区
        BarBuffer buffer = this.mBarBuffers[index];
        buffer.setPhases(phaseX, phaseY);
        buffer.setDataSet(index);
        buffer.setInverted(this.mChart.isInverted(dataSet.getAxisDependency()));
        buffer.setBarWidth(this.mChart.getBarData().getBarWidth());
        buffer.feed(dataSet); // 填充数据
        trans.pointValuesToPixel(buffer.buffer); // 转换为像素坐标

        // 1. 计算圆角半径和顶部圆形间距
        int rx = SizeUtils.dp2px(13f); // 圆角半径（13dp）
        int circleMargin = SizeUtils.dp2px(4f); // 顶部圆形与柱的间距（4dp）

        // 遍历所有柱
        for (int j = 0; j < buffer.size(); j += 4) {
            // 检查柱是否在可见区域内
            if (this.mViewPortHandler.isInBoundsLeft(buffer.buffer[j + 2])) {
                if (!this.mViewPortHandler.isInBoundsRight(buffer.buffer[j])) {
                    break;
                }

                int color = dataSet.getColor(j / 8); // 获取柱的颜色
                // 创建渐变颜色（顶部和底部使用相同颜色，但可调整透明度）
                int gradientTopColor = ColorUtils.setAlphaComponent(color, 1f);
                int gradientBottomColor = ColorUtils.setAlphaComponent(color, 0.5f);

                // 设置渐变着色器  直接使用渐变色
                mRenderPaint.setShader(new LinearGradient(
                        buffer.buffer[j], buffer.buffer[j + 3], // 渐变起始点（柱底部）
                        buffer.buffer[j], buffer.buffer[j + 1], // 渐变结束点（柱顶部）
                        gradientBottomColor, gradientTopColor, // 从底部颜色到顶部颜色
                        Shader.TileMode.MIRROR));

                // 绘制圆角矩形柱（+100隐藏底部数值）
                c.drawRoundRect(
                        buffer.buffer[j], // left
                        buffer.buffer[j + 1], // top
                        buffer.buffer[j + 2], // right
                        buffer.buffer[j + 3] + 100, // bottom (+100隐藏底部)
                        rx, rx, // x,y半径
                        this.mRenderPaint);

                mRenderPaint.setShader(null); // 清除着色器
                mRenderPaint.setColor(Color.WHITE); // 设置白色用于绘制顶部圆形

                // 计算顶部圆形的半径
//                float circleRadius = (buffer.buffer[j + 2] - buffer.buffer[j] - circleMargin * 2) / 2;
//                // 绘制顶部圆形
//                c.drawCircle(
//                        buffer.buffer[j] + circleRadius + circleMargin, // 圆心X（居中）
//                        buffer.buffer[j + 1] + circleMargin + circleRadius, // 圆心Y
//                        circleRadius,
//                        mRenderPaint);
            }
        }
    }
}